package com.t.bricks.bussiness.component.lucene;

import java.util.List;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import com.t.bricks.bussiness.util.lucene.LuceneFactory;
import com.t.bricks.model.Log;
import com.t.bricks.model.MsgEmity;
import com.t.bricks.utils.spring.ModuleUtil;

/**
 * 搜索引擎切面子类,专门处理删除数据时的关联操作
 */
@Component
@Aspect
public class LuceneAspectDel extends LuceneAspectBase {

	/**
	 * 定义切入点，切入点为'MsgEmity com.t.bricks.bussiness.db.dao.*.impl.*DaoImpl.del(?, Integer)'下的del函数,并且函数只有2个参数
	 */
	@Pointcut(value = "execution(public com.t.bricks.model.MsgEmity com.t.bricks.bussiness.db.dao.*.impl..*DaoImpl.del(*, Integer))"
			+ " || execution(public com.t.bricks.model.MsgEmity com.t.bricks.bussiness.db.dao.common.impl.CommonDaoImpl.del(*, Integer,boolean,Class))"
			+ " || execution(public com.t.bricks.model.MsgEmity com.t.bricks.bussiness.db.dao.common.impl.CommonDaoImpl.delByKey(String, Object, Integer, boolean, Class))"
			+ " || execution(public com.t.bricks.model.MsgEmity com.t.bricks.bussiness.db.dao.common.impl.CommonDaoImpl.dels(*, boolean, Class))")
	//@Pointcut(value = "execution(* com.t.bricks.bussiness.db.dao.*.impl..*DaoImpl.*(..))")
	@Override
	public void doLuceneAspect() {
	}
    
	/**
	 * 后置/返回值增强
     * @param joinPoint
     * @param result 被切点方法执行后的返回值
	 */
	@AfterReturning(returning="result", pointcut="doLuceneAspect()")
	public void afterReturning(JoinPoint joinPoint, Object result) {
		if (!isCanAop) {
			return;//不进行搜索引擎切面操作,退出
		}
		
		if (!(result instanceof MsgEmity)) {//不是返回MsgEmity,则说明已经改变
			MethodSignature signature = (MethodSignature) joinPoint.getSignature();
			String methodName = signature.getMethod().getName();
			Log.error("方法'", methodName, "'返回数据不是MsgEmity");
			return;
		}
		
		MsgEmity msgEmity = (MsgEmity)result;
		if (!msgEmity.isSuccess()) {
			return;//原方法执行失败,不处理
		}
		
		del(joinPoint, msgEmity);//多线程处理
	}

    /**
     * 环绕通知
     * @param joinPoint
     * @return
     * @throws Throwable
     */
	@Around("doLuceneAspect()")
	@Override
	public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
		return joinPoint.proceed();//执行原切面中的预定方法后返回内容
	}

	/**
	 * 删除数据
	 * @param joinPoint
	 * @param msgEmity
	 */
	private void del(JoinPoint joinPoint, MsgEmity msgEmity) {
		Object[] objs = joinPoint.getArgs();
		if (null == objs || objs.length < 1) {
			Log.error("搜索引擎删除数据失败，切面的参数数量不对!");
			return;
		}
		
		String core = getCore(joinPoint, sLuceneIndexPath);
		
		String sMonthName = joinPoint.getSignature().getName();
		
		if ("del".equalsIgnoreCase(sMonthName)) {
			ModuleUtil.runThread(() -> {//多线程方式重新构造缓存数据
				//String idName = "java.lang.String".equals(objs[0].getClass().getName()) ? "sId" : "iId";
				String id = String.valueOf(objs[0]);// del(String sId, Integer iVersion)
				String corePath = core;
				
				//crateLuceneCore(FjoinPoint, sLuceneIndexPath);//建立搜索库,不论是否成功都往下走
				LuceneFactory.del("luceneId", id, corePath);
			});
		
			return;
		}
		
		if ("delByKey".equals(sMonthName)) {
			ModuleUtil.runThread(() -> {//多线程方式重新构造缓存数据
				String keyName = String.valueOf(objs[0]);
				String keyValue = String.valueOf(objs[1]);
				String corePath = core;
				
				LuceneFactory.delByKey(keyName, keyValue, corePath);
			});
		
			return;
		}

		if ("dels".equals(sMonthName)) {
			ModuleUtil.runThread(() -> {//多线程方式重新构造缓存数据
				String corePath = core;
				List<?> list = (List<?>) objs[0];
				for (Object object : list) {
					String id = String.valueOf(object);
					LuceneFactory.del("luceneId", id, corePath);
				}
			});

			return;
		}
	}
	
}
